﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace ArchivumAeternumDesktop
{
    public class ListEditorViewModel : INotifyPropertyChanged
    {
        private List<string> _items;
        private string _selectedItem;
        private Visibility _isEditorVisible = Visibility.Collapsed;
        private string _editingItem;
        public bool? _addingItem;

        public event Action<string, string> ItemAdded;
        public event Action<string, string> ItemEdited;
        public event Action<string, string> ItemDeleted;

        public string Title { get; set; }

        public Visibility IsEditorVisible
        {
            get
            {
                return _isEditorVisible;
            }

            set
            {
                if (value != _isEditorVisible)
                {
                    _isEditorVisible = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public List<string> Items {
            get
            {
                return _items;
            }

            set
            {
                if (value != _items)
                {
                    _items = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public string SelectedItem 
        { 
            get 
            { 
                return _selectedItem;
            } 

            set
            {
                if (_selectedItem != value)
                {
                    _selectedItem = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public string EditingItem
        {
            get
            {
                return _editingItem;
            }

            set
            {
                if (_editingItem != value)
                {
                    _editingItem = value;
                    NotifyPropertyChanged();
                }
            }
        }

        public OkButton OkButton { get; set; }
        public CancelButton CancelButton { get; set; }
        public AddButton AddButton { get; set; }
        public EditButton EditButton { get; set; }
        public DeleteButton DeleteButton { get; set; }

        public ListEditorViewModel()
        {
            OkButton = new OkButton(this);
            CancelButton = new CancelButton(this);
            AddButton = new AddButton(this);
            EditButton = new EditButton(this);
            DeleteButton = new DeleteButton(this);
        }

        private void NotifyPropertyChanged([CallerMemberName] string propertyName = null)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;
    }

    public class OkButton : ICommand
    {
        private ListEditorViewModel _viewModel;

        public OkButton(ListEditorViewModel viewModel)
        {
            _viewModel = viewModel;

            _viewModel.PropertyChanged += (sender, args) =>
                {
                    if (args.PropertyName == "EditingItem" && CanExecuteChanged != null)
                    {
                        CanExecuteChanged(this, new EventArgs());
                    }
                };
        }

        public bool CanExecute(object parameter)
        {
 	        return !String.IsNullOrWhiteSpace(_viewModel.EditingItem);
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            if (!String.IsNullOrWhiteSpace(_viewModel.EditingItem) && !_viewModel._addingItem.Value)
            {
                _viewModel.Items.Remove(_viewModel.SelectedItem);
                _viewModel.Items.Add(_viewModel.EditingItem);
            }

            if (!String.IsNullOrWhiteSpace(_viewModel.EditingItem) && _viewModel._addingItem.Value)
            {
                List<string> items = _viewModel.Items.ToList();
                items.Add(_viewModel.EditingItem);
                _viewModel.Items = items;
            }

            _viewModel._addingItem = null;
            _viewModel.IsEditorVisible = Visibility.Collapsed;
        }
    }

    public class CancelButton : ICommand
    {
        private ListEditorViewModel _viewModel;

        public CancelButton(ListEditorViewModel viewModel)
        {
            _viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _viewModel._addingItem = null;
            _viewModel.IsEditorVisible = Visibility.Collapsed;
        }
    }

    public class AddButton : ICommand
    {
        private ListEditorViewModel _viewModel;

        public AddButton(ListEditorViewModel viewModel)
        {
            _viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            return true;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _viewModel._addingItem = true;
            _viewModel.IsEditorVisible = Visibility.Visible;
        }
    }

    public class EditButton : ICommand
    {
        private ListEditorViewModel _viewModel;

        public EditButton(ListEditorViewModel viewModel)
        {
            _viewModel = viewModel;

            _viewModel.PropertyChanged += (sender, args) =>
            {
                if (args.PropertyName == "SelectedItem" && CanExecuteChanged != null)
                {
                    CanExecuteChanged(this, new EventArgs());
                }
            };        
        }

        public bool CanExecute(object parameter)
        {
            return _viewModel.SelectedItem != null;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
            _viewModel._addingItem = false;
            _viewModel.IsEditorVisible = Visibility.Visible;

        }
    }

    public class DeleteButton : ICommand
    {
        private ListEditorViewModel _viewModel;

        public DeleteButton(ListEditorViewModel viewModel)
        {
            _viewModel = viewModel;
        }

        public bool CanExecute(object parameter)
        {
            return false;
        }

        public event EventHandler CanExecuteChanged;

        public void Execute(object parameter)
        {
        }
    }
}
